package com.augurit.wf.common.util;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.struts2.ServletActionContext;
import org.dozer.DozerBeanMapper;
import org.jbpm.api.HistoryService;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.cmd.Environment;
import org.jbpm.api.history.HistoryActivityInstance;
import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.api.history.HistoryTask;
import org.jbpm.api.model.Activity;
import org.jbpm.api.model.Transition;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.el.Expression;
import org.jbpm.pvm.internal.history.model.HistoryTaskImpl;
import org.jbpm.pvm.internal.history.model.HistoryTaskInstanceImpl;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
import org.jbpm.pvm.internal.task.TaskDefinitionImpl;
import org.jbpm.pvm.internal.task.TaskImpl;
import org.springframework.context.ApplicationContext;
import org.springside.modules.orm.Page;
import org.springside.modules.utils.SpringContextHolder;
import org.springside.modules.web.struts2.Struts2Utils;

import com.augurit.common.base.extmodel.BasicCombo;
import com.augurit.common.system.service.auth.ILoginUserService;
import com.augurit.common.util.ReflectionUtils;
import com.augurit.common.util.lang.CollectionUtils;
import com.augurit.common.util.lang.DateUtils;
import com.augurit.common.util.lang.StringUtils;
import com.augurit.gzcgwsp.wfex.common.service.IWfServiceEX;
import com.augurit.wf.bi.web.form.WfActElemPrivDefForm;
import com.augurit.wf.bi.web.form.WfBusInstanceForm;
import com.augurit.wf.bi.web.form.WfBusInstanceTaskForm;
import com.augurit.wf.bi.web.form.WfPrivControlForm;
import com.augurit.wf.common.constant.WfConstant;
import com.augurit.wf.common.entity.Jbpm4HistTask;
import com.augurit.wf.common.entity.Jbpm4Task;
import com.augurit.wf.common.form.TraceRecord;
import com.augurit.wf.common.form.WfBusBaseEntity;
import com.augurit.wf.common.form.WfBusSaveResult;
import com.augurit.wf.common.form.jbpm.ActivityForm;
import com.augurit.wf.common.form.jbpm.TransitionForm;
import com.augurit.wf.common.service.IWfService;
import com.augurit.wf.jbpmex.assignee.AssigneeParser;
import com.augurit.wf.jbpmex.assignee.AssigneeTreeNode;
import com.augurit.wf.jbpmex.task.multitask.MultiTaskDefinition;
import com.augurit.wf.mgmt.web.form.ProcInstBasicInfo;
import com.thoughtworks.xstream.XStream;

/**
 * 工作流工具类
 */
public class WfUtils {

	/**
	 * 通用打印表单
	 */
	public static String wfBusPrint(Object busFormObj) throws Exception{
		try{
			Map<String, String> variables = new HashMap<String, String>();
			String[] fields = ReflectionUtils.getFieldArray(busFormObj.getClass());
			
			for(String field : fields){
				Object value = ReflectionUtils.invokeGetterMethod(busFormObj, field);
				if(value != null){
					if(value instanceof Timestamp || value instanceof Date){
						Date date = (Date)value;
						String dateStr=DateUtils.dateTimeToString(date, DateUtils.YEAR_MOUTH_DAY_);
						variables.put(field, dateStr);
					}
					else{
						value=value.toString().replace("null", "");
					    if("null".equals(value.toString()))
					        variables.put(field, "");
					    else
					        variables.put(field, value.toString());
					}
				}
				else
					variables.put(field, "");
			}
			ServletActionContext.getRequest().setAttribute(WfConstant.PRINT_BUFFER, variables);
		}
		catch(Exception e){
			e.printStackTrace();
		}
		return WfConstant.PRINT;
	}
	
	public static Map<String, List<TraceRecord>> constructOpinionsMap(List<TraceRecord> list){
		Map<String, List<TraceRecord>> map = null;
		if(list != null && list.size() > 0){
			map = new HashMap<String, List<TraceRecord>>();
			List<TraceRecord> traceRecords = new ArrayList<TraceRecord>();
 	    	TraceRecord preTraceRecord = list.get(0);
 	    	traceRecords.add(preTraceRecord);
 	    	
 	    	TraceRecord curTraceRecord = null;
 	    	for(int i = 1; i < list.size(); i++){
 	    		curTraceRecord = list.get(i);
 	    		if(curTraceRecord.getActivityName().equals(preTraceRecord.getActivityName())){
 	    			traceRecords.add(curTraceRecord);
 	    		}
 	    		else{
 	    			map.put(preTraceRecord.getActivityName(), traceRecords) ;
 	    			preTraceRecord = curTraceRecord;
 	    			traceRecords = new ArrayList<TraceRecord>();
 	    			traceRecords.add(curTraceRecord);
 	    		}
 	    	}
 	    	map.put(preTraceRecord.getActivityName(), traceRecords);
 	    	
 	    }
		return buildData(map);
		//return map;
	}
	
	/**
	 * 重新构造map，城管委系统加入
	 * @return
	 */
	private static Map<String,List<TraceRecord>> buildData(Map<String,List<TraceRecord>> map){
		Map<String, List<TraceRecord>> datas = new HashMap<String, List<TraceRecord>>();
		if(map != null){
            Iterator it=map.entrySet().iterator();
            while(it.hasNext()){
         	   Map.Entry entrys=(Map.Entry)it.next();
         	   String key=(String) entrys.getKey();
         	    List<TraceRecord> traceRecords=(List<TraceRecord>) entrys.getValue();
         	   if(traceRecords.size()>0){
         		  TraceRecord record=null;
         		   for(int k=traceRecords.size()-1;k>=0;k--){
         			   record=traceRecords.get(k);
         				String outcome=record.getOutcome();
         				if(StringUtils.isNotBlank(outcome)){
         					if(outcome.indexOf("czgldyqsh")>-1 && 
             						record.getActivityName().indexOf("jbr")>-1){
             					datas.put("jbryqyj", traceRecords) ;
             					break;
             				}else{
             					datas.put(key,  traceRecords);
             					break;
             				}
         				}else{
         					datas.put(key,  traceRecords);
         					break;
         				}
         		   }
         	   }
          }
		}
		return datas;
	}
	
	
	
	
	/**
	 * 加载意见
	 */
	public static Map<String, List<TraceRecord>> loadWfOpinionsByTaskInstDbid(Long taskInstDbid, IWfService wfService){
		if(taskInstDbid != null){
	 	    List<TraceRecord> list = wfService.getTraceInfoOrderByActName(taskInstDbid);
	 	    
	 	    return constructOpinionsMap(list);
	    }
		return null;
	}
	
	
	
	public static Map<String, List<TraceRecord>> loadWfOpinionsByProcInstDbid(String procInstId, IWfService wfService, String activityName){
		if(procInstId != null && procInstId.trim().length() > 0 && activityName != null){
	 	    List<TraceRecord> list = wfService.getTraceInfo(procInstId);
	 	    return constructOpinionsMap(list);
	    }
		return null;
	}
	/**
	 * 格式化意见字符串
	 * @param traceRecords
	 * @return
	 */
	public static String formatOpitions(List<TraceRecord> traceRecords){
		StringBuilder opinionsStr = new StringBuilder("");
		if(traceRecords != null && traceRecords.size() > 0){
			if(traceRecords != null && traceRecords.size() > 0){
				
				for(TraceRecord traceRecord:traceRecords){
					if(traceRecord.getHandleComments() != null && traceRecord.getHandleComments().trim().length() > 0){
						opinionsStr.append(traceRecord.getHandleComments());
						opinionsStr.append("<br>");
						opinionsStr.append("&nbsp;&nbsp;");
						opinionsStr.append(traceRecord.getAssignee());
						opinionsStr.append("&nbsp;&nbsp;");
						opinionsStr.append(DateUtils.dateTimeToString(traceRecord.getSignTime(), DateUtils.YYYY_MM_DD_HH_MM_SS));
						opinionsStr.append("<br>");
					}
				}
			}
		}
		return opinionsStr.toString();
	}
	
	public static String printOpitions(List<TraceRecord> traceRecords){
		StringBuilder opinionsStr = new StringBuilder("");
		if(traceRecords != null && traceRecords.size() > 0){
			if(traceRecords != null && traceRecords.size() > 0){
				
				for(TraceRecord traceRecord:traceRecords){
					if(traceRecord.getHandleComments() != null && traceRecord.getHandleComments().trim().length() > 0){
						opinionsStr.append(traceRecord.getHandleComments());
						opinionsStr.append("  ");
						opinionsStr.append(traceRecord.getAssignee());
						opinionsStr.append(" （");
						opinionsStr.append(DateUtils.dateTimeToString(traceRecord.getSignTime(), DateUtils.YYYY_MM_DD_HH_MM_SS));
						opinionsStr.append("）");
					}
				}
			}
		}
		return opinionsStr.toString();
	}
	
	/**
	 * 转换为BasicCombo对象，同时去除开始节点和结束节点
	 */
	public static List<BasicCombo> convertValidActivities(List<? extends Activity> activities, boolean onlyTask){
		if(activities != null && activities.size() > 0){

			List<BasicCombo> list = new ArrayList();
			
			list.add(BasicCombo.getBlankItem());
			for(Activity activity : activities){
				if(!activity.getType().equals(WfConstant.ACTIVITY_TYPE_START)
						&& !activity.getType().equals(WfConstant.ACTIVITY_TYPE_END)
						&& !activity.getType().equals(WfConstant.ACTIVITY_TYPE_END_CANCEL)
						&& !activity.getType().equals(WfConstant.ACTIVITY_TYPE_END_ERROR)){
					
					if(onlyTask && activity.getType().equals(WfConstant.ACTIVITY_TYPE_TASK)){
						BasicCombo combo = new BasicCombo();
						combo.setLabel(activity.getChineseName());
						combo.setValue(activity.getName());
						list.add(combo);
					}
					else if(!onlyTask){
						BasicCombo combo = new BasicCombo();
						combo.setLabel(activity.getChineseName());
						combo.setValue(activity.getName());
						list.add(combo);
					}
				}
			}
			
			return list;
		}
		return null;
	}
	
	/**
	 * 获取流程实例ID列表
	 * @param list
	 * @return
	 */
	public static String[] getExecutionIdsByHistoryTasks(List<HistoryTask> list){
		if(list != null && list.size() > 0){
			Set<String> result = new HashSet();
			
			for(HistoryTask task : list){
				result.add(task.getExecutionId());
			}
			
			return CollectionUtils.toStringArray(result);
		}
		return null;
	}
	
	/**
	 * 获取流程实例ID列表
	 * @param list
	 * @return
	 */
	public static String[] getExecutionIdsByTasks(List<Task> list){
		if(list != null && list.size() > 0){
			Set<String> result = new HashSet();
			
			for(Task task : list){
				result.add(task.getExecutionId());
			}
			
			return CollectionUtils.toStringArray(result);
		}
		return null;
	}

	public static boolean isExpression(String express){
		if(express != null && express.trim().length() > 0){
			int startPos = express.indexOf("#{");
			int endPos = express.lastIndexOf("}");
			if(startPos == 0 && endPos == express.length()-1)
				return true;
		}
		return false;
	}
	
	public static List<ActivityForm> convertToActivityFormList(ProcessDefinitionImpl processDefinition,List<? extends Activity> activities, boolean onlyTask){
		if(activities != null && activities.size() > 0){
			List<ActivityForm> list = new ArrayList();
			
			for(Activity activity : activities){
				if(!activity.getType().equals(WfConstant.ACTIVITY_TYPE_START)
						&& !activity.getType().equals(WfConstant.ACTIVITY_TYPE_END)
						&& !activity.getType().equals(WfConstant.ACTIVITY_TYPE_END_CANCEL)
						&& !activity.getType().equals(WfConstant.ACTIVITY_TYPE_END_ERROR)){
					
					if(onlyTask && activity.getType().equals(WfConstant.ACTIVITY_TYPE_TASK)){
						list.add(convertToActivityForm(processDefinition,activity));
					}
					else if(!onlyTask){
						list.add(convertToActivityForm(processDefinition,activity));
					}
				}
			}
			
			return list;
		}
		return null;
	}
	
	public static List<TransitionForm> convertToTransitionFormList(ProcessDefinitionImpl processDefinition ,List<? extends Transition> transitions){
		if(transitions != null && transitions.size() > 0){
			List<TransitionForm> list = new ArrayList<TransitionForm>();
			
			for(Transition transition : transitions)
				list.add(convertToTransitionForm(processDefinition,transition));

			return list;
		}
		else
			return null;
	}
	
	public static ActivityForm convertToActivityForm(ProcessDefinitionImpl processDefinition ,Activity activity){
		if(activity != null){
			ActivityForm form = new ActivityForm();
			form.setName(activity.getName());
			form.setChineseName(activity.getChineseName());
			String message =  getMessageForActivity(processDefinition,activity);
			form.setMessage(message);
			return form;
		}else
			return null;
	}
	
	public static TransitionForm convertToTransitionForm(ProcessDefinitionImpl processDefinition,Transition transition){
		if(transition != null){
			TransitionForm form = new TransitionForm();
			form.setName(transition.getName());
			form.setDestination(convertToActivityForm(processDefinition,transition.getDestination()));
			return form;
		}else
			return null;
	}

	public static List<ActivityForm> convertToActivityFormList(ProcessDefinitionImpl processDefinition, String[] rangeActivityNames, Map<String, ? extends Activity> allActivities, boolean onlyTask){
		if(rangeActivityNames != null && rangeActivityNames.length > 0
				&& allActivities != null && allActivities.size() > 0){
			
			List<ActivityForm> list = new ArrayList();
			
			for(String activityName : rangeActivityNames){
				
				Activity activity = allActivities.get(activityName);
				
				if(activity != null){
					
					if(onlyTask && !activity.getType().equals(WfConstant.ACTIVITY_TYPE_TASK))
						break;
					
					list.add(convertToActivityForm(processDefinition,activity));
				}
			}
			
			return list;
		}
		return null;
	}
	
	/**
	 * 
	 * @param list
	 * @return
	 */
	public static boolean isAllTasksNotSigned(List<Task> list){
		boolean bool =  false;
		if(list != null && list.size()>0){
			for(Task task : list){
				if(task.getSignTime() != null){
					return false;
				}
				else
					bool =  true;
			}
		}
		return bool;
	}
	
	/**
	 * 
	 * @param list
	 * @return
	 */
	public  static boolean isAllHisTasksNotSigned(List<HistoryTask> list){
		boolean bool =  false;
		if(list != null && list.size()>0){
			for(HistoryTask task : list){
				if(task.getSignTime() != null){
					return false;
				}
				else
					bool =  true;
			}
		}
		return bool;
	}
	/**
	 * 获取主Task
	 * @return
	 */
	public static String getMainTaskId(List<Task> list){
		if(list != null && list.size()>0){
			for(Task task:list){
				TaskImpl taskImpl = (TaskImpl)task;
				if(taskImpl.getSuperTask()== null)
					return task.getId();
			}
		}
		return null;
	}

	/**
	 * 根据hisTaskId获取对应的HistoryActivityInstanceImpl
	 * @param environment
	 * @param taskId
	 * @return
	 */
	public static HistoryTaskInstanceImpl getHisActInst(Environment environment,String executionId,String taskId){
		if(environment != null && StringUtils.isNotBlank(executionId) && StringUtils.isNotBlank(taskId)){
			 HistoryService historyService = environment.get(HistoryService.class);
			List<HistoryActivityInstance> list = historyService.createHistoryActivityInstanceQuery().executionId(executionId).list();
			if(list != null && list.size()>0)
				for(HistoryActivityInstance hisActInst:list){
					if(hisActInst instanceof HistoryTaskInstanceImpl){
						HistoryTaskInstanceImpl hisTaskInst = (HistoryTaskInstanceImpl)hisActInst;
						HistoryTaskImpl historyTask = hisTaskInst.getHistoryTask();
						if(historyTask != null && historyTask.getId().equals(taskId)){
							return hisTaskInst;
						}
					}
				}
		}
		return null;
	}

	/**
	 * 根据hisTaskId获取对应的HistoryActivityInstanceImpl
	 * @param environment
	 * @param taskId
	 * @return
	 */
	public static HistoryTaskInstanceImpl getHistoryTaskInstanceByHisTaskId(Environment environment,String hisTaskId){
		if(environment != null && StringUtils.isNotBlank(hisTaskId)){
			HistoryService historyService = environment.get(HistoryService.class);
			
			HistoryTaskImpl historyTask = (HistoryTaskImpl)historyService.createHistoryTaskQuery().taskId(hisTaskId).uniqueResult();
			
			List<HistoryActivityInstance> list = historyService.createHistoryActivityInstanceQuery()
																.executionId(historyTask.getExecutionId())
																.activityName(historyTask.getActivityName())
																.list();
			if(list == null)
				return null;
			
			for(HistoryActivityInstance hisActInst:list){
				if(hisActInst instanceof HistoryTaskInstanceImpl){
					HistoryTaskInstanceImpl hisTaskInst = (HistoryTaskInstanceImpl)hisActInst;
					HistoryTaskImpl tempHistoryTask = hisTaskInst.getHistoryTask();
					
					if(tempHistoryTask != null){
						Set<HistoryTaskImpl> subHistoryTaskImpls = tempHistoryTask.getSubTasks();
						
						if(tempHistoryTask.getId().equals(hisTaskId)){
							return hisTaskInst;
						}else if(subHistoryTaskImpls != null){
							for (HistoryTaskImpl subHistoryTaskImpl : subHistoryTaskImpls) {
								if(subHistoryTaskImpl.getId().equals(hisTaskId))
									return hisTaskInst;
							}
						}
					}
				}
			}
		}
		return null;
	}
	
	//给Activity设置信息
	public static String getMessageForActivity(ProcessDefinitionImpl processDefinition,Activity activity){
		String message = null;
		if(processDefinition != null && activity != null && activity.getType().equals("task")){
			TaskDefinitionImpl taskDefinition = processDefinition.getTaskDefinition(activity.getName());
			MultiTaskDefinition multiTaskDefinition =taskDefinition.getMultiTaskDefinition();
			
			//普通任务
			if(multiTaskDefinition == null){
				message = "该工作项节点选择用户数为1";
			}
			//多工作项任务
			else{
				message = "该工作项节点选择用户数大于或等于2";
			}
		}
		return message;
	}
	
	public static boolean isSystemTask(TaskImpl task){
		if(task.getAssignee() != null && task.getAssignee().equals(WfConstant.TASK_ASSIGNEE_SYSTEM))
			return true;
		else
			return false;
	}
	
	/**
	 * 是否为多工作项人工节点
	 * @param task
	 * @return
	 */
	public static boolean isMultiTask(Task task){
		if(task != null && task.getTaskType() != null 
				&& task.getTaskType().equals(WfConstant.TASK_TYPE_MULTITASK))
			return true;
		else
			return false;
	}

	public static <T extends WfBusBaseEntity> void renderWfBusSaveJson(WfBusInstanceTaskForm task, T form){
		if(form != null && form.getId() != null && task != null && task.getTaskInstDbid() != null 
				&& task.getMasterEntityKey() != null && task.getMasterEntityKey().trim().length() > 0){
			
			WfBusSaveResult result = new WfBusSaveResult(true, form, task);
			Struts2Utils.renderJson(result);
		}else{
			WfBusSaveResult result = new WfBusSaveResult(false, "1.任务实例为空;2.任务实例没有主键;3.任务实例没有附带主业务实体信息;4.业务对象为空或没有主键;5.没有启动流程权限。");
			Struts2Utils.renderJson(result);
		}
	}
	
	public static void renderWfFailtureJson(String errorMsg){
		Struts2Utils.renderJson("{\"success\":false,\"errorMsg\":\"" + errorMsg + "\"}");
	}
	
	public static void renderWfTakeBackMsg(boolean success){
		String msg = success ? "成功取回任务" : "该任务不能取回";
		Struts2Utils.renderText(msg);
	}
	public static void renderWfReturnBackMsg(boolean success){
		String msg = success ? "成功回退任务" : "该任务不能回退";
		Struts2Utils.renderText(msg);
	}
	public static String convertToProcessDefinitionId(String wfDefKey, Integer wfDefVersion){
		if(wfDefKey != null && wfDefKey.trim().length() > 0 && wfDefVersion != null){
			return wfDefKey + "-" + wfDefVersion;
		}else
			return null;
	}
	
	public static String getPageElementsOrderClause(String wfPageElementEntityAlias, boolean groupSort){
		if(groupSort)
			return " order by " + wfPageElementEntityAlias + ".elementType asc," + wfPageElementEntityAlias + ".elementGroup asc," + wfPageElementEntityAlias + ".groupSortNo asc, " + wfPageElementEntityAlias + ".elementSortNo asc";
		else
			return " order by "+ wfPageElementEntityAlias + ".elementType asc," + wfPageElementEntityAlias  + ".elementGroup asc," + wfPageElementEntityAlias + ".elementSortNo asc";
	}
	
	public static List<HistoryTaskImpl> convertToHistoryTaskList(Set<HistoryTaskImpl> historyTaskSet){
		if(historyTaskSet != null && historyTaskSet.size() > 0){
			List<HistoryTaskImpl> list = new ArrayList();
			list.addAll(historyTaskSet);
			return list;
		}
		return null;
	}
	
	/**
	 * 去掉自由流节点中包含的人工流转节点
	 * @param form
	 */
	public static void removeRepeatActivity(WfBusInstanceTaskForm form){
		if(form != null){
			
			List<ActivityForm> freeList = form.getFreeActivities();
			List<TransitionForm> tranList = form.getNextTransitions();
			
			if(freeList != null && freeList.size() > 0){
				List<ActivityForm> freeListCopy = new ArrayList();
				
				for(ActivityForm freeForm : freeList){
					
					boolean repeat = false;
					for(TransitionForm tranForm : tranList){
						if(freeForm.getName().equals(tranForm.getDestination().getName())){
							repeat = true;
							break;
						}
					}
					
					//没有重复的
					if(!repeat /*&& !freeForm.getName().equals(form.getActivityName())*/){
						freeListCopy.add(freeForm);
					}
				}
				
				//保存没有与人工流节点重复的自由流节点
				form.setFreeActivities(freeListCopy);
			}
		}
	}

	public static boolean isValidAssignee(Jbpm4Task task, String userKey){
		boolean result = false;
		
		if(task != null && userKey != null && userKey.trim().length() > 0){
			if(task.getAssignee() != null && task.getAssignee().equals(userKey)){
				result = true;
			}else if(task.getAgent() != null && task.getAgentStartDate() != null && task.getAgentEndDate() != null){
				Date now = new Date();
				if(task.getAgent().equals(userKey) && task.getAgentStartDate().before(now) && task.getAgentEndDate().after(now)){
					result = true;
				}
			}
		}
		
		return result;
	}
	
	/**
	 * 清除发送信息，以免影响下次发送操作
	 * @param instance
	 */
	public static void clearWfSendInfo(WfBusInstanceTaskForm form){
		if(form != null){
			form.setDestActivityName(null);
			form.setDestActivityChineseName(null);
			form.setAssignee(null);
			form.setAssigneeName(null);
		}
	}
	

	public static String getAssigneesFromHistTaskS(List<Jbpm4HistTask> list){
		String assignees = null;
		if(list != null && list.size()>0){
			StringBuffer sb = new StringBuffer();
			for( int i = 0; i<list.size();i++){
				Jbpm4HistTask histTask = list.get(i);
				if(i==list.size()-1)
					sb.append(histTask.getAssignee());
				else
					sb.append(histTask.getAssignee()+","); 				
			}
			assignees = sb.toString();
		}
		return assignees;
	}
	
	public static String renderXmlForAssigneeTreeNode(Object obj){
		XStream xstream = new XStream();
		xstream.setMode(XStream.NO_REFERENCES);
		xstream.alias("node", AssigneeTreeNode.class);
		xstream.useAttributeFor(String.class);
		xstream.useAttributeFor(Long.class);
		xstream.useAttributeFor(boolean.class);
		xstream.addImplicitCollection(AssigneeTreeNode.class, "children");
		return xstream.toXML(obj);
	}
	
	public static boolean containsString(String assignees[],String startWfUserKey){
		if(assignees != null && assignees.length > 0 
				&& startWfUserKey != null && startWfUserKey.trim().length()>0){
			for(String assignee: assignees){
				if(startWfUserKey.equals(assignee))
					return true;
			}
		}
		return false;
	}
	/**
	 * 是否为多工作项人工节点
	 * @param task
	 * @return
	 */
	public static boolean isMultiTask(HistoryTask hisTask){
		if(hisTask != null && hisTask.getTaskType() != null 
				&& hisTask.getTaskType().equals(WfConstant.TASK_TYPE_MULTITASK))
			return true;
		else
			return false;
	}
	public static String formatPrivControlKey(String elementCode, String templateCode, String version, String viewName, String activityName){
		StringBuilder sb = new StringBuilder();
		sb.append(elementCode);
		sb.append(WfPrivControlForm.SEPARATOR);
		sb.append(templateCode);
		sb.append(WfPrivControlForm.SEPARATOR);
		
		sb.append(version);
		sb.append(WfPrivControlForm.SEPARATOR);
		sb.append(viewName);
		if(viewName.equals(WfActElemPrivDefForm.DB_ZB_VIEW)){
			sb.append(WfPrivControlForm.SEPARATOR);
			sb.append(activityName);
		}
		return sb.toString();
		
	}
	
	public static  String getAssigneeFromHistoryTasks(List<HistoryTask> list){
		String assignee = null;
		if(list != null && list.size() > 0){
			List<String> assigneeList = new ArrayList<String>();
			for(HistoryTask hisTask :list)
				assigneeList.add(hisTask.getAssignee());
			
			assignee = StringUtils.convertStringListToString(assigneeList,AssigneeParser.ASSIGNEE_SEPARATOR);
		}
		return assignee;
	}
	
	public static void main(String[] args){
		System.out.println(isExpression("#{abc}"));
	}
	

	
//	public static void convertToTaskSummary(Object[] objs, WfBusInstance entity){
//		if(objs != null && objs.length > 0){
//			for(int i=1; i<objs.length; i++){
//				if(i == 1)
//					entity.setBusMemo1(objs[i] != null ? objs[i].toString() : null);
//				else if(i == 2)
//					entity.setBusMemo2(objs[i] != null ? objs[i].toString() : null);
//				else if(i == 3)
//					entity.setBusMemo3(objs[i] != null ? objs[i].toString() : null);
//				else if(i == 4)
//					entity.setBusMemo4(objs[i] != null ? objs[i].toString() : null);
//				else if(i == 5)
//					entity.setBusMemo4(objs[i] != null ? objs[i].toString() : null);
//			}
//		}
//	}
	
	/**
	 * 同步业务实体信息到汇总字段中
	 */
	public static <T extends WfBusBaseEntity> void syncSummary(T source, WfBusInstanceForm destination, DozerBeanMapper dozer){
		
		//默认同步策略
		dozer.map(source, destination);

		//TODO: 自定义同步策略
		
	}
	
	/**
	 * 同步业务实体信息到汇总字段中
	 */
	public static void syncSummary(Map map, WfBusInstanceForm destination, DozerBeanMapper dozer){
		
		//默认同步策略
		if(map != null && map.size() > 0){
			Iterator it = map.entrySet().iterator();
			
			int stringIndex = 1;
			int dateIndex = 1;
			int doubleIndex = 1;
			
			while(it.hasNext()){
				Map.Entry entry = (Map.Entry)it.next();
				String key = (String)entry.getKey();
				Object value = entry.getValue();
				
				if(!key.equalsIgnoreCase("id")){
					if(value instanceof String){
						putStringSummary(destination, (String)value, stringIndex);
						stringIndex++;
					}
					else if(value instanceof Date){
						putDateSummary(destination, (Date)value, dateIndex);
						dateIndex++;
					}
					else if(value instanceof Integer){
						putDoubleSummary(destination, ((Integer)value).doubleValue(), doubleIndex);
						doubleIndex++;
					}
					else if(value instanceof Float){
						putDoubleSummary(destination, ((Float)value).doubleValue(), doubleIndex);
						doubleIndex++;
					}
					else if(value instanceof Double){
						putDoubleSummary(destination, (Double)value, doubleIndex);
						doubleIndex++;
					}
				}
			}
		}		
	}
	
	private static void putStringSummary(WfBusInstanceForm form, String value, int stringIndex){
		if(stringIndex == 1){
			form.setBusMemo1(value);
		}
		else if(stringIndex == 2){
			form.setBusMemo2(value);
		}
		else if(stringIndex == 3){
			form.setBusMemo3(value);
		}
		else if(stringIndex == 4){
			form.setBusMemo4(value);
		}
		else if(stringIndex == 5){
			form.setBusMemo5(value);
		}
		else if(stringIndex == 6){
			form.setBusMemo6(value);
		}
	}
	
	private static void putDateSummary(WfBusInstanceForm form, Date value, int dateIndex){
		if(dateIndex == 1){
			form.setBusDate1(value);
		}
		else if(dateIndex == 2){
			form.setBusDate2(value);
		}
		else if(dateIndex == 3){
			form.setBusDate3(value);
		}
		else if(dateIndex == 4){
			form.setBusDate4(value);
		}
	}
	
	private static void putDoubleSummary(WfBusInstanceForm form, Double value, int doubleIndex){
		if(doubleIndex == 1){
			form.setBusNum1(value);
		}
		else if(doubleIndex == 2){
			form.setBusNum2(value);
		}
	}
	
	public static WfBusInstanceTaskForm getCurTaskInfo(String busEntityKey, Long taskInstDbId){
		WfBusInstanceTaskForm result = new WfBusInstanceTaskForm();
//		result.setBusEntityName(busEntityName);
		result.setMasterEntityKey(busEntityKey);
//		result.setWfInstanceId(processInstance.getId());
		result.setTaskInstDbid(taskInstDbId);
		return result;
	}
	
	public static List<String> getCommonActivityNames(List<? extends Activity> curProcActivity,  List<? extends Activity> preProcActivity){
		List<String> commonActivities = new ArrayList<String>();
		for(int i = 0; i < curProcActivity.size(); i++){
			
			Activity activity = curProcActivity.get(i);
			
			for(int j = 0; j < preProcActivity.size(); j++){
				if(activity.getName().equals(preProcActivity.get(j).getName())){
					commonActivities.add(preProcActivity.get(j).getName());
				}
			}
		}
		return commonActivities;
	}
	public static List<HistoryTask> convertHisActInstListToHisTaskList(List<HistoryActivityInstance> hisActInsts){
		List<HistoryTask> result = null;
		if(hisActInsts != null && hisActInsts.size() > 0){
			result = new ArrayList();
			
			for(HistoryActivityInstance hisActInst : hisActInsts){
				if(hisActInst.getType().equals(WfConstant.ACTIVITY_TYPE_TASK)){
					HistoryTaskInstanceImpl hisTaskActInst = (HistoryTaskInstanceImpl)hisActInst;
					HistoryTask historyTask = hisTaskActInst.getHistoryTask();
					
					if(historyTask != null){
						result.add(historyTask);
						
						HistoryTaskImpl historyTaskImpl = (HistoryTaskImpl)historyTask;
						Set<HistoryTaskImpl> subTasks = historyTaskImpl.getSubTasks();
						if(subTasks != null && subTasks.size() > 0){
							result.addAll(subTasks);
						}
					}
				}
			}
		}
		return result;
	}
	
	/**
	 * 将历史任务转换为历史跟踪列表
	 * @param historyTasks
	 * @return
	 */
	public static List<TraceRecord> convertToTraceInfoList(List<HistoryTask> historyTasks){
		 if(historyTasks != null && historyTasks.size() > 0){
			 List<TraceRecord> result = new ArrayList();
			  ApplicationContext ctx = SpringContextHolder.getApplicationContext();
			  IWfServiceEX wfServiceEX=(IWfServiceEX) ctx.getBean("wfServiceImplEX");
			 for(HistoryTask historyTask : historyTasks){
				 if(historyTask.getAssignee() != null && historyTask.getAssignee().trim().length() > 0
						 && !historyTask.getAssignee().equals(WfConstant.TASK_ASSIGNEE_SYSTEM)){
					 
					 TraceRecord rec = new TraceRecord();
					
					 rec.setActivityName(historyTask.getActivityName());
					 rec.setActivityChineseName(historyTask.getActivityChineseName());
					 
					 List agentList =  wfServiceEX.getAgentNameById(Long.parseLong(historyTask.getId()));
					 if(agentList != null && agentList.size()>0){						 
						 String agenName = (String)((Object [])agentList.get(0))[1];
						 if(StringUtils.isNotBlank(agenName) && !agenName.equals("系统管理员")){
							 rec.setAssignee(agenName);
						 }else{
							 rec.setAssignee(historyTask.getAssigneeName());
						 }
					 }
					 
					 rec.setCreateDate(historyTask.getCreateTime());
					 rec.setEndDate(historyTask.getEndTime());
					 rec.setHandleComments(historyTask.getHandleComments());
					 rec.setHandleCommentsTime(historyTask.getHandleCommentsTime());
					 rec.setSignTime(historyTask.getSignTime());
					 rec.setOutcome(historyTask.getOutcome());
//					 if(historyTask.getState()!= null && historyTask.getState().equals(Task.STATE_COMPLETED))
					 String currentTaskState = historyTask.getState();
					 if(HistoryTask.STATE_COMPLETED.equals(currentTaskState))
						 rec.setStatus(WfConstant.TASK_STATE_COMPLETED);
					 else if(HistoryTask.STATE_OBSOLETE.equals(currentTaskState))
						 rec.setStatus(WfConstant.TASK_STATE_OBSOLETE);
					 else
						 rec.setStatus(WfConstant.TASK_STATE_OPEN);

					 result.add(rec);
				 }
			 }
			 
			 return result;
		 }
		 return null;
	}
	
	//根据HistoryProcessInstance和ProcessInstance组装ProcInstBasicInfo
	public static ProcInstBasicInfo convertToProcInstBasicInfo(HistoryProcessInstance histProcInst,ProcessInstance procInst){
		ProcInstBasicInfo basicInfo = null;
		if(histProcInst != null && procInst != null){
			basicInfo = new ProcInstBasicInfo();
			ExecutionImpl execution = (ExecutionImpl)procInst;
			
			basicInfo.setDbid(execution.getDbid());
			if(execution.getParent() != null)
				basicInfo.setParentId(execution.getParent().getDbid());
			if(histProcInst.getProcessDuedate() != null){
				basicInfo.setIsOutTime(histProcInst.getProcessDuedate().getTime()- new Date().getTime() >0 ? "是" : "否");
			}else
				basicInfo.setIsOutTime("否");
			basicInfo.setActivityName(execution.getActivityName());
			
			basicInfo.setProcInstId(histProcInst.getProcessInstanceId());
			basicInfo.setProcdefid(histProcInst.getProcessDefinitionId());
			basicInfo.setState(histProcInst.getState());
			basicInfo.setStartTime(histProcInst.getStartTime());
			basicInfo.setProcessDuedate(histProcInst.getProcessDuedate());
		}
		return basicInfo;
	}
	
	public static String buildTaskSummaryOrderBy(String taskEntity, String instEntity,
			String templateEntity, String templateTypeEntity, Page page, String groupBy, String groupDir){
		
		String groupOrder = "";
		String pageOrder = "";
		
		if(groupBy != null && groupBy.trim().length() > 0){
			if(groupBy.equals("templateTypeName")){
				groupOrder = buildSummaryOrderByPart(templateTypeEntity, groupBy, groupDir);
			}
			else if(groupBy.equals("templateName")){
				groupOrder = buildSummaryOrderByPart(templateEntity, groupBy, groupDir);
			}
		}
		
		if(page != null && page.getOrderBy() != null){
			if(page.getOrderBy().equals("create")){
				pageOrder = buildSummaryOrderByPart(taskEntity, page.getOrderBy(), page.getOrder());
			}
			else if(page.getOrderBy().equals("templateTypeName")){
				pageOrder = buildSummaryOrderByPart(templateTypeEntity, page.getOrderBy(), page.getOrder());
			}
			else if(page.getOrderBy().equals("templateName")){
				pageOrder = buildSummaryOrderByPart(templateEntity, page.getOrderBy(), page.getOrder());
			}
			else{
				pageOrder = buildSummaryOrderByPart(instEntity, page.getOrderBy(), page.getOrder());
			}
		}
		
		String sepa = groupOrder.trim().length() == 0 ? "" : ",";
		
		
		return " order by " + groupOrder + sepa + pageOrder;
	}
	
	public static String buildBusSummaryOrderBy(String instEntity, String procEntity, 
			String templateEntity, String templateTypeEntity, Page page, String groupBy, String groupDir){
		
		String groupOrder = "";
		String pageOrder = "";
		
		if(groupBy != null && groupBy.trim().length() > 0){
			if(groupBy.equals("templateTypeName")){
				groupOrder = buildSummaryOrderByPart(templateTypeEntity, groupBy, groupDir);
			}
			else if(groupBy.equals("templateName")){
				groupOrder = buildSummaryOrderByPart(templateEntity, groupBy, groupDir);
			}
		}
		
		if(page != null && page.getOrderBy() != null){
			if(page.getOrderBy().equals("procStartdate")){
				pageOrder = buildSummaryOrderByPart(procEntity, "start", page.getOrder());
			}
			else if(page.getOrderBy().equals("templateTypeName")){
				pageOrder = buildSummaryOrderByPart(templateTypeEntity, page.getOrderBy(), page.getOrder());
			}
			else if(page.getOrderBy().equals("templateName")){
				pageOrder = buildSummaryOrderByPart(templateEntity, page.getOrderBy(), page.getOrder());
			}
			else{
				pageOrder = buildSummaryOrderByPart(instEntity, page.getOrderBy(), page.getOrder());
			}
		}
		
		String sepa = groupOrder.trim().length() == 0 ? "" : ",";
		
		
		return " order by " + groupOrder + sepa + pageOrder;
	}
	
	private static String buildSummaryOrderByPart(String entityAlias, String orderBy, String order){
		if(orderBy != null && orderBy.trim().length() > 0)
			return " " + entityAlias + "." + orderBy + " " + (order != null ? order : "");
		else
			return "";
	}
	
	public static void replaceRangeForNullAssigneeExp(TaskDefinitionImpl taskDefinition){
		Expression assigneeExpression = taskDefinition.getAssigneeExpression();
		if(assigneeExpression == null){
			String assigneeRange = taskDefinition.getAssigneeRange();
			if(assigneeRange != null && assigneeRange.trim().length() > 0)
				taskDefinition.setAssigneeExpression(Expression.create(assigneeRange));
		}
	}
}
